﻿using FNN.Models;
using FNN.Networks;
using FNN.SourcePoints;
using LiveCharts;
using LiveCharts.Configurations;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;

namespace GraphicFNN
{
    /// <summary>
    /// Логика взаимодействия для ChartingWindow.xaml
    /// </summary>
    public partial class NetworkActivityWindow : Window, INotifyPropertyChanged
    {
        private int _pointsCount = 250;
        private double _initialFunds = 100000.0;

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(String name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        public NetworkActivityWindow(FinancialNetwork target, List<DateSourcePoint> dataSource)
        {
            InitializeComponent();
            DataContext = this;

            var mapper = Mappers.Xy<FinancialModel>()
                .X(model => model.Date.Ticks)
                .Y(model => model.Value);

            //lets save the mapper globally.
            Charting.For<FinancialModel>(mapper);

            //the values property will store our values array
            BuyingValues = new ChartValues<FinancialModel>();
            SellingValues = new ChartValues<FinancialModel>();
            SourceValues = new ChartValues<FinancialModel>();

            XAxis.LabelFormatter = value => new DateTime((long)value).ToString("dd/MM/yyyy HH:mm");

            PopulateSummary(target, dataSource);
            PopulateActivity(target, dataSource);
        }

        protected void PopulateSummary(FinancialNetwork target, List<DateSourcePoint> dataSource)
        {
            var profitPercent = ((target.Funds - _initialFunds) / _initialFunds * 100).ToString("F2");
            LblNetworkOperationCount.Content = target.Transactions.Count;
            LblNetworkOperationCountTitle.Content = "Количество транзакций:";
            LblNetworkResultsPercent.Content = profitPercent + "%";
            LblNetworkResultsPercentTitle.Content = "Прибыльность:";
            LblNetworkResults.Content = target.Funds.ToString("F2");
            LblNetworkResultsTitle.Content = "Капитал сети:";
        }

        public void PopulateActivity(FinancialNetwork target, List<DateSourcePoint> dataSource)
        {
            LblNetworkName.Content = target.NetworkName;

            var minimumDate = (target.Transactions.Count > 0) ? target.Transactions.Min(o => o.TransactionDate).AddDays(-7) : dataSource.Min(o => o.PointDate);
            var maximumDate = (target.Transactions.Count > 0) ? target.Transactions.Max(o => o.TransactionDate).AddDays(7) : dataSource.Max(o => o.PointDate);
            var filteredDataSource = dataSource.Where(o => o.PointDate <= maximumDate && o.PointDate >= minimumDate).ToList();
            int neededIndexes = filteredDataSource.Count() / _pointsCount;

            foreach (var point in filteredDataSource)
            {
                var pointIndex = filteredDataSource.IndexOf(point);
                if ((pointIndex % neededIndexes) == 0)
                    SourceValues.Add(new FinancialModel() { Date = point.PointDate, Value = point.Coordinates.Values.ElementAt(0) });
            }

            foreach (var transaction in target.Transactions)
            {
                if (transaction.TransactionType)
                {
                    SellingValues.Add(new FinancialModel() { Date = transaction.TransactionDate, Value = dataSource.First(o => o.PointDate.Date == transaction.TransactionDate.Date).Coordinates.Values.ElementAt(0) });
                }
                else
                {
                    BuyingValues.Add(new FinancialModel() { Date = transaction.TransactionDate, Value = dataSource.First(o => o.PointDate.Date == transaction.TransactionDate.Date).Coordinates.Values.ElementAt(0) });
                }
            }

            OnPropertyChanged("SourceValues");
            OnPropertyChanged("BuyingValues");
            OnPropertyChanged("SellingValues");
        }

        public ChartValues<FinancialModel> SourceValues { get; set; }
        public ChartValues<FinancialModel> BuyingValues { get; set; }
        public ChartValues<FinancialModel> SellingValues { get; set; }
    }
}
